Namespace ServerConsole

    ''' <summary>
    ''' Contains the routines for processing console input and commands
    ''' </summary>
    ''' <remarks></remarks>
    Friend Class ConsoleCommands

        ''' <summary>
        ''' Handles any commanded excecuted from the console
        ''' </summary>
        ''' <param name="cmd">String containing the command</param>
        ''' <param name="arg">Arraylist containing the argument Strings for the command</param>
        ''' <remarks></remarks>
        Public Shared Sub ParseCommand(ByVal cmd As String, ByVal arg As ArrayList)

            If GetFlag("-?", arg, Nothing) Then

                Select Case LCase(cmd)
                    Case "exit"
                        Output.AddLine("# Command[exit] Help")
                        Output.AddLine("# Are you stupid? This will close the server *sigh*")

                    Case "createacc"
                        CreateAccHelp()

                    Case "delacc"
                        DelAccHelp()

                    Case "gmrights"
                        GMRightsHelp()

                    Case "svrmode"
                        SvrModeHelp()

                End Select

            Else

                Select Case LCase(cmd)

                    Case ""
                        'no command, do nothing

                    Case "help"
                        ListCommands()

                    Case "exit"
                        Globals.bShutdown = True

                    Case "createacc"
                        CreateAcc(arg)

                    Case "delacc"
                        DelAcc(arg)

                    Case "gmrights"
                        GMRights(arg)

                    Case "svrmode"
                        SvrMode(arg)

                    Case "logquery"
                        QueryLogs(arg)

                    Case "entermaintain"
                        Globals.bUnderMaintainance = True
                        Output.AddLine("\B0\F5SV>\F0\B8 \F3Server entered maintainance mode\F0")

                    Case "exitmaintain"
                        Globals.bUnderMaintainance = False
                        Output.AddLine("\B0\F5SV>\F0\B8 \F2Server left maintainance mode\F0")

                    Case Else
                        Output.AddLine("# Unknown command: " & LCase(cmd))

                End Select

            End If

        End Sub

        ''' <summary>
        ''' Displays a list of valid commands in the console
        ''' </summary>
        ''' <remarks></remarks>
        Private Shared Sub ListCommands()

            Output.AddLine("# exit       createacc  delacc     gmrights   svrmode    ")

        End Sub

        ''' <summary>
        ''' 
        ''' </summary>
        ''' <param name="flag">String containing the flag to retrieve (eg. "-gm")</param>
        ''' <param name="arg">ArrayList containing the argument Strings</param>
        ''' <param name="ret">ByRef String to return any flag related string (eg. a command of "gmrights -u UserName -gm -f", ret would be "UserName", if flag was specified as "-u")</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function GetFlag(ByVal flag As String, ByVal arg As ArrayList, ByRef ret As String) As Boolean

            If arg.Count > 0 Then
                For i As Integer = 0 To arg.Count - 1
                    If LCase(arg(i)) = LCase(flag) Then
                        If i + 1 < arg.Count Then
                            If Not Left(arg(i + 1), 1) = "-" Then
                                ret = arg(i + 1)
                            End If
                        End If
                        Return True
                    End If
                Next
            End If

            ret = ""
            Return False

        End Function

        Private Shared Sub CreateAcc(ByVal arg As ArrayList)

            Dim username As String = ""
            Dim password As String = ""
            Dim email As String = ""
            Dim isgm As Boolean

            If GetFlag("-u", arg, username) And GetFlag("-p", arg, password) Then
                isgm = GetFlag("-gm", arg, Nothing)
                GetFlag("-e", arg, email)
                If email = "" Then email = "a@a.com"
                Dim login As NewUserLogin
                login.STR_USERNAME = username
                login.STR_PASSMD5 = MD5Hash(password)
                login.STR_EMAIL = email
                Functions.CreateAccount(login, isgm, True)
            Else
                CreateAccHelp()
            End If

        End Sub

        Private Shared Sub CreateAccHelp()

            Output.AddLine("# Command[createacc] Help")
            Output.AddLine("# format: createacc -u <username> -p <password> [-gm]")
            Output.AddLine("# flags:")
            Output.AddLine("#  -u: username")
            Output.AddLine("#  -p: password")
            Output.AddLine("# -gm: (optional) creates an entry in the GM table for the account")

        End Sub

        Private Shared Sub DelAcc(ByVal arg As ArrayList)

            Dim username As String = ""
            Dim enable As Boolean

            If GetFlag("-u", arg, username) Then
                enable = GetFlag("-e", arg, Nothing)
                Functions.DeleteAccount(username, enable, True)
            Else
                DelAccHelp()
            End If

        End Sub

        Private Shared Sub DelAccHelp()

            Output.AddLine("# Command[delacc] Help")
            Output.AddLine("# format: delacc -u <username> [-e]")
            Output.AddLine("# flags:")
            Output.AddLine("#  -u: username")
            Output.AddLine("#  -e: (optional) re-enables a previously deleted account")

        End Sub

        Private Shared Sub GMRights(ByVal arg As ArrayList)

            Dim username As String = ""
            Dim gm As Boolean
            Dim filter As Boolean

            If GetFlag("-u", arg, username) Then
                gm = GetFlag("-gm", arg, Nothing)
                filter = GetFlag("-f", arg, Nothing)
                Functions.SetGMRights(username, filter, gm, True)
                Dim conn As Connection = Socket.SockServer.ConnectionList.GetConnFromUserName(username)
                If Not conn Is Nothing Then
                    conn.IsGM = gm
                End If
            Else
                GMRightsHelp()
            End If

        End Sub

        Private Shared Sub GMRightsHelp()

            Output.AddLine("# Command[gmrights] Help")
            Output.AddLine("# format: gmrights -u <username> [-gm] [-f]")
            Output.AddLine("# flags:")
            Output.AddLine("#  -u: username")
            Output.AddLine("# -gm: (optional) enables gm mode on the account")
            Output.AddLine("#  -f: (optional) disables IP filtering for the account")

        End Sub

        Private Shared Sub SvrMode(ByVal arg As ArrayList)

            Dim fMode As String = "" 'mode flag
            Dim bMode As Boolean 'mode boolean
            Dim fTimeOut As String = "" 'time to change in minutes string
            Dim iTimeout As Integer 'time to change in minutes integer

            'check for -m flag
            If GetFlag("-m", arg, fMode) Then
                'convert mode flag to boolean
                Try
                    bMode = CBool(fMode)
                Catch ex As Exception
                    'parse failed display help and exit sub
                    SvrModeHelp()
                    Exit Sub
                End Try

                If GetFlag("-t", arg, fTimeOut) Then
                    'convert time flag to boolean
                    Try
                        iTimeout = Integer.Parse(fTimeOut)
                    Catch ex As Exception
                        'parse failed display help and exit sub
                        SvrModeHelp()
                        Exit Sub
                    End Try
                Else
                    iTimeout = 0
                End If

                InitServerMaintanceMode(bMode, iTimeout)

            Else
                SvrModeHelp()
            End If

        End Sub

        Private Shared Sub InitServerMaintanceMode(mode As Boolean, mintoswitch As Integer)

            'abort the switch thread if running
            If Not SwitchThread Is Nothing Then
                If isSwitchMaintainMode And SwitchThread.IsAlive Then
                    SwitchThread.Abort()
                End If
            End If

            ToMaintainMode = mode

            If mintoswitch > 0 Then
                ToMaintainTimeToSwitch = DateTime.Now.AddMinutes(mintoswitch)
                StartServerMaintananceModeThread()
            Else
                SwitchMaintainanceMode()
            End If

        End Sub

        Private Shared Sub StartServerMaintananceModeThread()

            isSwitchMaintainMode = True

            SwitchThread = New System.Threading.Thread(AddressOf SwitchMaintainanceModeWaitThread)
            SwitchThread.Start()

        End Sub

        Private Shared SwitchThread As System.Threading.Thread

        Private Shared isSwitchMaintainMode As Boolean
        Private Shared ToMaintainMode As Boolean
        Private Shared ToMaintainTimeToSwitch As DateTime

        Private Shared Sub SwitchMaintainanceModeWaitThread()

            Try

                Do Until Globals.bShutdown

                    If ToMaintainTimeToSwitch < DateTime.Now Then
                        SwitchMaintainanceMode()
                        Exit Sub
                    End If

                    Threading.Thread.Sleep(1000)
                    Windows.Forms.Application.DoEvents()

                Loop

            Catch ex As System.Threading.ThreadAbortException

            End Try

        End Sub

        Private Shared Sub SwitchMaintainanceMode()

            If ToMaintainMode Then

                'TODO: disconnect everyone but GM connections

                Socket.SockServer.EndAllNonGMConnection()


            End If

            Globals.bUnderMaintainance = ToMaintainMode

            isSwitchMaintainMode = False
            Output.AddLine("MM> Switched maintainance mode to " & CStr(ToMaintainMode))

        End Sub

        Private Shared Sub SvrModeHelp()

            Output.AddLine("# Command[svrmode] Help")
            Output.AddLine("# format: svrmode -m # [-t #]")
            Output.AddLine("# enables gm login only mode")
            Output.AddLine("# flags:")
            Output.AddLine("#  -m: maintainance status 0 (0 off/1 on)")
            Output.AddLine("#  -t: (optional) time to maintainance mode in minutes")
            Output.AddLine("#  no flags = toggle mode")

        End Sub

        Private Shared Sub QueryLogs(arg As ArrayList)

            On Error Resume Next

            'var for query
            Dim query As String = ""
            Dim c As Integer = 0

            'itterate through args to create a query string
            If arg.Count > 1 Then
                c = arg.Count - 2
            End If

            For idx As Integer = 0 To c
                query &= arg(idx)
                If idx < arg.Count - 1 Then query &= " "
            Next

            If IsNumeric(arg(arg.Count - 1)) And arg.Count > 1 Then
                Logger.LogSearch(query, arg(arg.Count - 1))
            Else
                Logger.LogSearch(query, 99)
            End If
        End Sub

    End Class

End Namespace